package com.cans.lightning.business.lowcode.service.impl;

import com.cans.lightning.base.mapper.IBaseMapper;
import com.cans.lightning.base.service.impl.BaseServiceImpl;
import com.cans.lightning.business.lowcode.dao.AppFormDao;
import com.cans.lightning.business.lowcode.dto.AppFormDto;
import com.cans.lightning.business.lowcode.dto.AppTableDto;
import com.cans.lightning.business.lowcode.dto.AppTableFieldDto;
import com.cans.lightning.business.lowcode.entity.AppForm;
import com.cans.lightning.business.lowcode.enums.TableTypeEnum;
import com.cans.lightning.business.lowcode.manager.AppIndexManager;
import com.cans.lightning.business.lowcode.manager.form.AppFormBeanManager;
import com.cans.lightning.business.lowcode.manager.form.bean.AppFormBean;
import com.cans.lightning.business.lowcode.manager.form.bean.FormFieldBean;
import com.cans.lightning.business.lowcode.mapper.AppFormMapper;
import com.cans.lightning.business.lowcode.service.api.IAppFormDefinitionService;
import com.cans.lightning.business.lowcode.service.api.IAppTableService;
import org.beetl.sql.mapper.BaseMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * 应用信息
 *
 * @author shencan
 * @date 2020/6/14 20:53
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class AppFormDefinitionServiceImpl extends BaseServiceImpl<AppForm, AppFormDto, String> implements IAppFormDefinitionService {

    private static final Logger logger = LoggerFactory.getLogger(AppFormDefinitionServiceImpl.class);

    @Resource
    private AppFormDao appFormDao;
    @Resource
    private AppFormMapper appFormMapper;
    @Resource
    private IAppTableService appTableService;
    @Resource
    private AppIndexManager appIndexManager;
    @Resource
    private AppFormBeanManager appFormBeanManager;


    @Override
    public BaseMapper<AppForm> getDaoImpl() {
        return appFormDao;
    }

    @Override
    public IBaseMapper<AppForm, AppFormDto, String> getMapperImpl() {
        return appFormMapper;
    }

    @Override
    public List<AppFormDto> getByAppId(String appId) {
        return appFormMapper.toDtos(appFormDao.createLambdaQuery().andEq(AppForm::getAppId, appId).select());
    }

    @Override
    public void saveOrUpdateDto(AppFormDto appFormDto) {
        AppForm appForm = this.toEntity(appFormDto);
        super.saveOrUpdate(appForm);
        AppTableDto mainTable = this.getAppTable(appForm);
        appTableService.saveOrUpdate(mainTable);

    }

    private AppTableDto getAppTable(AppForm appForm) {
        String dbTableName = appIndexManager.getNextMainTableName();
        AppTableDto mainTable = new AppTableDto();
        mainTable.setFormId(appForm.getId());
        mainTable.setTableType(TableTypeEnum.MAIN.getKey());
        mainTable.setDbTableName(dbTableName);
        mainTable.setAppId(appForm.getAppId());
        mainTable.setTableName(appForm.getFormName());
        return mainTable;
    }

    @Override
    public void saveToDb(AppFormDto appFormDto) {
        String dbTableName = appIndexManager.getNextMainTableName();
        this.saveOrUpdateDto(appFormDto);
        AppTableDto mainTable = appFormDto.getMainTable();
        mainTable.setFormId(appFormDto.getId());
        mainTable.setTableType(TableTypeEnum.MAIN.getKey());
        mainTable.setDbTableName(dbTableName);
        mainTable.setAppId(appFormDto.getAppId());
        mainTable.setTableName(appFormDto.getFormName());
        appTableService.saveOrUpdate(mainTable);
        List<AppTableDto> tableDtoList = appFormDto.getSonTables();
        if (!CollectionUtils.isEmpty(tableDtoList)) {
            for (AppTableDto appTableDto : tableDtoList) {
                appTableDto.setFormId(appFormDto.getId());
                appTableService.saveOrUpdate(appTableDto);
            }
        }
    }

    @Override
    public AppFormDto getInfo(String id) {
        AppFormDto appFormDto = this.getDtoById(id);
        appTableService.findByFormId(id);
        appFormDto.setMainTable(appTableService.getManTableByFormId(appFormDto.getId()));
        appFormDto.setSonTables(appTableService.getSonTablesByFormId(appFormDto.getId()));
        return appFormDto;
    }

    @Override
    public String getNextFieldIndex(String formId) {
        return appTableService.getNextFieldIndex(formId);
    }

    @Override
    public AppFormBean formBeanDesign(String id) {
        try {
            return appFormBeanManager.formBeanDesign(id);
        } catch (ExecutionException e) {
            logger.info("编辑formBea失败");
        }
        return null;
    }

    @Override
    public void saveToDb(AppFormBean appFormBean) throws ExecutionException {
        appFormBeanManager.saveToDb(appFormBean);
    }

    @Override
    public AppFormBean getFormBean(String formId) {
        return appFormBeanManager.getFormBean(formId);
    }

    @Override
    public void mergeBaseInfo(AppFormBean appFormBean) throws ExecutionException {
        appFormBeanManager.mergeBaseInfo(appFormBean);
    }

    @Override
    public void removeEdit(String formId) {
        appFormBeanManager.removeEdit(formId);
    }

    @Override
    public AppTableFieldDto addField(AppTableFieldDto tableFieldDto) throws ExecutionException {
        AppFormBean editBean = appFormBeanManager.getEditBean(tableFieldDto.getFormId());
        FormFieldBean formFieldBean = editBean.addField(tableFieldDto);
        tableFieldDto.setId(formFieldBean.getId());
        tableFieldDto.setDbFieldName(formFieldBean.getDbFieldName());
        return tableFieldDto;
    }

}
